#include "strategy.h"

#include <time.h>

#include "business_def.h"

Strategy::Strategy(/* args */)
    : pbdef(BusinessDef::getInstance())
{
}

Strategy::~Strategy()
{
}

bool Strategy::exceptCurTimes(std::vector<ExceptTime> exceptList_, struct tm _tt)
{
	bool ret = false;
	for (unsigned int i = 0, Esize = static_cast<unsigned int>(exceptList_.size()); i<Esize; ++i)
	{
		if (exceptList_.at(i).myear > 0 && _tt.tm_year != exceptList_.at(i).myear)
		{
			continue;
		}
		if (exceptList_.at(i).mmon > 0 && _tt.tm_mon != exceptList_.at(i).mmon)
		{
			continue;
		}
		if (exceptList_.at(i).mday > 0 && _tt.tm_mday != exceptList_.at(i).mday)
		{
			continue;
		}
		ret = true;
		break;
	}
	return ret;
};

bool Strategy::mapCurTimes(std::vector<PlanTime> &_pts)
{
	for (unsigned int i=0, pSIze= static_cast<unsigned int>(_pts.size()); i<pSIze; ++i)
	{
		if (mapCurTime(_pts[i]))
		{
			return true;
		}
	}
	return false;
};

bool Strategy::mapCurTime(PlanTime &_pt)
{
	time_t _t = time(NULL);
	struct tm _tt;
#ifdef WIN32	
	localtime_s(&_tt, &_t);
#else
	localtime_r(&_t, &_tt);
#endif
	_tt.tm_year += 1900;
	_tt.tm_mon += 1;

	if (_pt.myear > 0 && _tt.tm_year != _pt.myear) 
	{
		_pt.flag = false;
		return false;
	}
	if (_pt.mmon > 0 && _tt.tm_mon != _pt.mmon) 
	{
		_pt.flag = false;
		return false;
	}
	if (_pt.mday > 0 && _tt.tm_mday != _pt.mday) 
	{
		_pt.flag = false;
		return false;
	}
	if (_pt.mhour > 0 && _tt.tm_hour != _pt.mhour) 
	{
		_pt.flag = false;
		return false;
	}
	if (_pt.mmin > 0 && _tt.tm_min != _pt.mmin) 
	{
		_pt.flag = false;
		return false;
	}
	int wdayVal = 0x01;
	if (_pt.wday >= 0 && !((wdayVal << _tt.tm_wday) & _pt.wday)) 
	{
		_pt.flag = false;
		return false;
	}
	if (_pt.flag == false)
	{
		_pt.flag = true;//因为定时只到分钟级别,为防止重复设置了该标记
		bool ret = !exceptCurTimes(_pt.exceptList, _tt);//对符合的定时条件追加排除日期
		return ret;
	}
	else
	{
		return false;
	}
};

unsigned int Strategy::getTVMin(time_t _t)
{
	unsigned int min_ = 0;
	struct tm _tt;
#ifdef WIN32
	localtime_s(&_tt, &_t);
#else
	localtime_r(&_t, &_tt);
#endif
	min_ = 60 * _tt.tm_hour + _tt.tm_min;
	return min_;
};

inline bool Strategy::comRangeUIntVal(unsigned int val_, unsigned int valA_, unsigned int valB_)
{
	if (valA_ < valB_) 
	{
		if (val_ >= valA_ && val_ < valB_)
		{
			return true;
		}
	}
	else 
	{
		if (val_ >= valA_ || val_ < valB_)
		{
			return true;
		}
	}
	return false;
}

bool Strategy::inWorkTime(unsigned int min_, std::vector<TVProperty> timeVS)
{
	if (timeVS.empty()) 
	{
		return true;
	}
	for (unsigned int i = 0, tSize = static_cast<unsigned int>(timeVS.size()); i < tSize; ++i)
	{
		if (comRangeUIntVal(min_, timeVS.at(i).allStartMin, timeVS.at(i).allEndMin))
		{
			return true;
		}
	}
	return false;
};

bool Strategy::mapSleepTime(std::vector<TVProperty> timeVS, PlanSleep &_ps)
{
	//总条件,是否在时段范围
	time_t _t = time(NULL);
	unsigned int min_ = getTVMin(_t);
	bool tt_in_work = inWorkTime(min_,timeVS);
	if (!tt_in_work)
	{
		return false;
	}
	
	if (_ps.tt < _t)
	{
		_ps.tt = static_cast<unsigned int>(_t) + _ps.interval;
		return true;
	}
	else {
		return false;
	}
};

bool Strategy::conditionJude(std::vector<TVProperty> timeVS,std::vector<PlanCondition> _plancons,bool planflag)
{
	//总条件,是否在时段范围
	time_t _t = time(NULL);
	unsigned int min_ = getTVMin(_t);
	bool tt_in_work = inWorkTime(min_, timeVS);
	if (!tt_in_work)
	{
		return false;
	}
	//分条件
	bool _condition = true;//所有值是否满足条件
	bool ishasChange = false;//其中是否有变化值
	for (std::vector<PlanCondition>::iterator itc = _plancons.begin();
		itc != _plancons.end(); ++itc)
	{
		bool _valMap = false;
		bool _valChange = false;
		//正确取回值,并该值被标记为变化
		if (pbdef->getConditionJude(itc->devID, itc->pID, itc->val, _valMap
            , _valChange,planflag,itc->compare))
		{
			if (_valChange&&itc->ValChange)//变化并变化有效
			{
				ishasChange = true;
			}
			//判定值是否满足要求
			if (!_valMap)
			{
				_condition = false;
				break;
			}
		}
		else 
		{
			_condition = false;
			break;
		}
	}
	return (_condition&&ishasChange);
};

bool Strategy::mapStartTime(std::vector<TVProperty> timeVS)
{
	//总条件,是否在时段范围
	time_t _t = time(NULL);
	unsigned int min_ = getTVMin(_t);
	bool tt_in_work = inWorkTime(min_, timeVS);
	if (!tt_in_work)
	{
		return false;
	}
	return true;
};

int Strategy::getCurTVDay()
{
	time_t _t = time(NULL);
	// int min_ = 0;
	struct tm _tt;
#ifdef WIN32
	localtime_s(&_tt, &_t);
#else
	localtime_r(&_t, &_tt);
#endif
	return  _tt.tm_mday;
};

